package checkers3d.presentation;

import checkers3d.logic.GameMaster;
import checkers3d.storage.DataManagerUtil;
import java.awt.Color;
import java.awt.Point;
import java.util.LinkedList;

/**
 * Displays a list of filenames sans extension in a GUIContainer. Adds buttons
 * for performing a task, or exiting the menu.
 *
 * @author Ruben Acuna
 */
public class WindowFileBrowser extends GUIContainer
{
    /**
     * Y axis value along which buttons will be centered.
     */
    protected final int CONTROL_BUTTON_AXIS = GameEngine.WINDOW_SIZE.y - 100;

    /**
     * Size of pixel pad between file names.
     */
    protected final int TEXT_PAD = 4;

    /**
     * List of the GUILabels that were generated for files.
     */
    protected LinkedList<GUILabel> availableFilenameLabels = new LinkedList<GUILabel>();

    /**
     * Title of the file list being displayed.
     */
    private String title;

    /**
     * The folder of files to display.
     */
    private String folder;

    /**
     * Reference to the start button.
     */
    private GUIButton buttonStart;

    /**
     * File extension type for this window file browser.
     */

    // Static so that the constructor can see it...
    private String FILE_EXTENSION;


    /**
     * Creates a GUICotainer and adds the needed components. Builds the list of
     * files.
     *
     * @param title Title of file list.
     * @param folder Folder to list files from.
     * @param size Size of window.
     */
    public WindowFileBrowser(String title, String folder, String FILE_EXTENSION, Point size)
    {
        super(size);

        this.title = title;
        this.folder = folder;
        this.FILE_EXTENSION = FILE_EXTENSION;

        LinkedList<IDrawable> buttons = new LinkedList<IDrawable>();

        //add background image.
        add(new GUIPictureBox("Background.png", new Point()));

        //create the start button with behavior. ObserverReturn is to prevent crashing.
        buttonStart = new GUIButton("button-start.png", null, new ObserverReturn());
        buttons.add(buttonStart);

        //create the return button with behavior.
        buttons.add(new GUIButton("button-return.png", null, new ObserverReturn()));

        //add the buttons to the GUIContainer.
        for(IDrawable component : buttons)
            add(component);

        //compute the positions of the buttons
        UtilGUI.computeLayoutSpanning(getSize(), CONTROL_BUTTON_AXIS, buttons);

        setupFilenameList(FILE_EXTENSION);
    }

    /**
     * Builds and displays a list of the sfile currently available.
     */
    protected void setupFilenameList(String FILE_EXTENSION)
    {
        String[] files = DataManagerUtil.getFilenames(folder, FILE_EXTENSION);
        Point labelLocation = new Point(100, 100);

        //add title label.
        add(new GUILabel(title, Color.GREEN, (Point)labelLocation.clone()));

        labelLocation.translate(10, 15);

        //added labels for each file.
        for(int i = 0; i < files.length; i++)
        {
            GUILabel fileLabel;

            fileLabel = new GUILabel(files[i], Color.WHITE, (Point)labelLocation.clone());

            add(fileLabel);
            availableFilenameLabels.add(fileLabel);

            labelLocation.translate(0, fileLabel.getRenderResource().getHeight() + TEXT_PAD);
        }
    }
    /**
     * Selects a file by making its label yellow and showing a preview image
     * and desciption.
     *
     * @param name Scenario file.
     */
    protected void selectFile(String name)
    {
        //set the selected file yellow and the others white
        for(GUILabel label : availableFilenameLabels)
            if(label.getText().equals(name))
                label.setColor(Color.YELLOW);
            else
                label.setColor(Color.WHITE);
    }

    /**
     * Returns the name of the currently selected file.
     *
     * @return Name of file.
     */
    public String getSelectedFilename()
    {
        String name = null;

        for(GUILabel label : availableFilenameLabels)
            if(label.getColor() == Color.YELLOW)
            {
                name = label.getText();
                break;
            }

        return name;
    }

    /**
     * Sets the current observer of the start button.
     *
     * @param observer A IInputObject for the start button.
     */
    public void setStartObserver(IInputObserver observer)
    {
        buttonStart.setObserver(observer);
    }
    
    /**
     * Processes a user click by funneling it to internal components and/or
     * update the selected file.
     *
     * @param  position  Point object containing the relative screen coordinates
     *                   of the click.
     */
    @Override
    public void onClick(Point position)
    {
        super.onClick(position);

        for(GUILabel label : availableFilenameLabels)
        {
            Point relative = new Point(position.x - label.getDrawPosition().x,
                                       position.y - label.getDrawPosition().y);

            if(label.getRenderResource().containsPoint(relative))
            {
                selectFile(label.getText());
                break;
            }
        }
    }

    /**
     * Returns a string representation of this object containing it's class name.
     *
     * @return String representation.
     */
    @Override
    public String toString()
    {
        return getClass().getName();
    }
    
    /**
     * An observer for a button that returns user to the main menu.
     */
    protected class ObserverReturn implements IInputObserver
    {
        /**
         * Returns the user to the main menu.
         *
         * @param position Location of click within button.
         */
        public void onClick(Point position)
        {
            GameMaster.getInstance().removeTopGUIContainer();
        }

         /**
         * Key press observer that does nothing.
         *
         * @param key Key that was pressed.
         */
        public void onKeyPress(char key)
        {
            //do nothing.
        }
    }
}
